import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.filechooser.FileSystemView;

import junit.framework.TestCase;


public class UnitTests extends TestCase {

	//public static String compiler_folder = "../comp/bin/";
	public static String compiler_folder = System.getProperty("user.dir") + "/bin/";
	public static String src_path_1 = "examples/Eval-Set1-YAL/";
	public static String jasmin_path_1 = "generated_jasmin/";
	public static String file_path_1 = "generated_code/";
	
	public static String src_path_2 = "examples/Eval-Set2-YAL/";
	
	public static String src_path_3 = "examples/Eval-Set3-YAL/";
	public static String jasmin_path_3 = "generated_jasmin/set3";
	public static String file_path_3 = "generated_code/set3";
	
	public static String src_path_4 = "examples/MyTests/";
	public static String jasmin_path_4 = "generated_jasmin/mytests";
	public static String file_path_4 = "generated_code/mytests";
	
	private String[] files = {	"all_1", "all_2", "all_3", "all_4", "all_5",
			"av_1", "av_2",
			"f_1", "f_2", "f_3",
			"fv_1", "fv_2", "fv_3",
			"i_1", "i_2", "i_3", "i_4",
			"if_1", "if_2", "if_3", "if_4",
			"iw_1", "iw_2", "iw_3",
			"iwafv_1",
			"iwf_1", "iwf_2", "iwf_3", "iwf_4",
			"iwfv_1",
			"rec_fact_1", "rec_fact_2",
			"v_1", "v_2",
			"w_1", "w_2", "w_3", "w_4",
			"wf_1", "wf_2",
			"wfv_1", "wfv_2", "wfv_3", "wfv_4", "wfv_5"
	};
	
	private String[] files_2 = {	"f_call_iwfv_2g1",
									"iwfv_2g1"
	};
	
	private String[] files_4 = {	"test1"
	};
	
	/*public void testCompiler(){
		try {
			//TestProgram("all_1", results[0]);
			for(int i = 0; i < files.length; i++){
				TestProgram(src_path_1, jasmin_path_1, file_path_1, files[i], results[i]);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}*/
	
/*	public void test_test1(){
		try {
			TestProgram(src_path_4, jasmin_path_4, file_path_4, files_4[0]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}*/
	
	public void test_iwfv_2g1(){
		try {
			TestProgram(src_path_2, jasmin_path_1, file_path_1, files_2[1]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_f_call_iwfv_2g1(){
		try {
			TestProgram(src_path_2, jasmin_path_1, file_path_1, files_2[0]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wfv_5(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[44]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wfv_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[43]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wfv_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[42]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wfv_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[41]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wfv_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[40]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wf_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[39]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_wf_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[38]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_w_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[37]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_w_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[36]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_w_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[35]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_w_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[34]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_v_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[33]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_v_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[32]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_rec_fact_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[31]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_rec_fact_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[30]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_iwfv_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[29]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_iwf_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[28]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iwf_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[27]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iwf_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[26]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iwf_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[25]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iwafv_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[24]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iw_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[23]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iw_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[22]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_iw_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[21]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_if_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[20]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_if_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[19]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_if_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[18]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_if_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[17]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public void test_i_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[16]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_i_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[15]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_i_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[14]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_i_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[13]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_fv_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[12]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_fv_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[11]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_fv_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[10]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_all_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[0]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_all_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[1]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_all_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[2]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_all_4(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[3]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_all_5(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[4]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_av_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[5]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_av_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[6]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test_f_1(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[7]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_f_2(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[8]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void test_f_3(){
		try {
			TestProgram(src_path_1, jasmin_path_1, file_path_1, files[9]);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	
	private void TestProgram(String src_path, String jasmin_path, String file_path, String filename) throws Exception{
		
		Runtime run = Runtime.getRuntime();
		
		String[] argsC = {"java", "-classpath" , compiler_folder, "yal2jvm", "-o" , src_path + filename + ".yal"};
		Process compiler = run.exec(argsC, null, null);
		
		// Accumulate text from the output stream
		BufferedReader inc = new BufferedReader(new InputStreamReader(compiler.getInputStream()));
		String lc, rec = "";
		try {
			while ((lc = inc.readLine()) != null) {
				rec += lc + "\n";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		System.out.println(rec);
		
		compiler.waitFor();
		
		System.out.println("Compiler Done\n\n\n");
		
		String[] argsJ = {"java", "-jar", "jasmin.jar", "-d", file_path, filename + ".j"};
		Process jasmin = run.exec(argsJ, null, null);
		jasmin.waitFor();
		
		// Accumulate text from the output stream
		BufferedReader inj = new BufferedReader(new InputStreamReader(compiler.getInputStream()));
		String lj, rej = "";
		try {
			while ((lj = inj.readLine()) != null) {
				rej += lj + "\n";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		System.out.println(rej);
		
		System.out.println("Jasmin Done");
		
		String result = loadFile(src_path + filename + "_expected.txt");
		
		String[] argsP = {"java", "-classpath", file_path, filename};
		Process p = run.exec(argsP, null, null);
		String res = "";
		
		// Accumulate text from the error stream
		BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
		String line;
		try {
			while ((line = err.readLine()) != null) {
				System.err.println(line);
				res += line + "\n";
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Accumulate text from the output stream
		BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
		try {
			while ((line = in.readLine()) != null) {
				res += line + "\n";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		p.waitFor();
		
		System.out.println("Given result: " + res);
		System.out.println("Expected result: " + result);
		assertEquals(result, res);
	}
	
	private String loadFile(String filename) throws Exception{
		BufferedReader in = new BufferedReader(new FileReader(filename));
		String line;
		String res = "";
		try {
			while ((line = in.readLine()) != null) {
				res += line + "\n";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return res;
	}
}
